package org.example.selector;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Scanner;

/**
 * 转发客户端
 */
public class Demo2Client {
    private final Selector selector;
    private final SocketChannel socketChannel;

    /**
     * 初始化构造函数
     */
    Demo2Client() {
        try {
            //开启选择器
            selector = Selector.open();
            //开启Socket,设置ip端口,设置非阻塞
            socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 10040));
            socketChannel.configureBlocking(false);
            //Socket注册至选择器
            socketChannel.register(selector, SelectionKey.OP_READ);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * main
     *
     * @param args args
     */
    public static void main(String[] args) {
        //创建客户端
        Demo2Client demo2Client = new Demo2Client();
        //开启新线程循环读取数据
        new Thread(() -> {
            while (demo2Client.socketChannel.isConnected()) {
                demo2Client.read();
            }
        }).start();
        //循环监听键盘输入
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String s = scanner.next();
            demo2Client.send(s);
        }
    }

    /**
     * 发送
     *
     * @param msg 消息
     */
    public void send(String msg) {
        try {
            //通道写入消息
            socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读
     */
    public void read() {
        try {
            //开启选择器
            int count = selector.select();
            if (count > 0) {
                //遍历选择器事件
                for (SelectionKey key : selector.selectedKeys()) {
                    //读事件
                    if (key.isReadable()) {
                        //获取socket通道和缓冲区
                        SocketChannel channel = (SocketChannel) key.channel();
                        //创建缓冲区
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        //读取数据至缓冲区
                        int read = channel.read(byteBuffer);
                        if (read > -1) {
                            System.out.println(new String(byteBuffer.array()));
                        } else {
                            System.out.println("连接关闭");
                            channel.close();
                        }
                        //删除当前事件key
                        selector.selectedKeys().remove(key);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
